import { Add, Remove } from '@mui/icons-material';
import {
  Box,
  Button,
  ButtonGroup,
  List,
  ListItemButton,
  ListItemIcon,
  ListItemText,
  styled,
} from '@mui/material';
import { useEffect, useRef, useState } from 'react';
import { BsBalloon, BsBalloonFill } from 'react-icons/bs';
import { MaterialParams } from './types';
import { materialSetter } from './MaterialSetter';
import {
  CMEVENTS
} from '@amcax/base'
import {
  userEvents
} from '@app-cad/module';

const StyledListBox = styled(Box)(({ theme }) => ({
  display: 'flex',
  height: '115px',
  maxHeight: '115px',
  width: '100%',
  border: `1px solid ${theme.palette.divider}`,
  borderRadius: '5px',
  backgroundColor: theme.palette.background.default,
  overflowY: 'auto',
  '.MuiList-root': {
    width: '100%',
  },
}));

const StyledActionBox = styled(Box)(({ theme }) => ({
  display: 'flex',
  justifyContent: 'center',
  alignItems: 'start',
  paddingLeft: theme.spacing(0.5),
  '.MuiButtonGroup-root .MuiButtonBase-root': {
    minWidth: '20px',
    padding: 0,
  },
}));

export default function MaterialListBox({
  dxid,
  materials,
  faceIndex,
}: MaterialParams) {
  const dxidRef = useRef(dxid);
  const faceIndexRef = useRef(faceIndex);
  const [_materials, setMaterials] = useState<any[]>([]);
  const [selectedIndex, setSelectedIndex] = useState<number>(-1);

  useEffect(() => {
    console.log('MaterialListBox useEffect', materials);
    dxidRef.current = dxid;
    faceIndexRef.current = faceIndex;
    setMaterials(materials);
    registerEvents();
  }, []);
  useEffect(() => {
    if (_materials.length > 0) {
      if (selectedIndex === -1) {
        selectMaterial(0);
      } else {
        selectMaterial(selectedIndex);
      }
    }
    if (_materials.length == 0) {
      selectMaterial(-1);
    }
  }, [_materials]);

  const registerEvents = () => {
    userEvents.on(
      CMEVENTS.MATERIAL_MODEL_SELECTED,
      ({ dxid, materials, faceIndex }) => {
        dxidRef.current = dxid;
        faceIndexRef.current = faceIndex;
        setMaterials(materials);
        setSelectedIndex(-1);
      },
    );
    userEvents.on(CMEVENTS.MATERIAL_ADDED, async (material: any) => {
      setMaterials((preMaterials) => {
        const newMaterials = getNewMaterials(preMaterials, material);
        return [...newMaterials];
      });
    });
    userEvents.on(CMEVENTS.MATERIAL_UPDATED, async (material: any) => {
      setMaterials((preMaterials) => {
        preMaterials.forEach((item, index) => {
          if (
            item.id === material.id &&
            item.dxid === material.dxid &&
            item.faceIndex === material.faceIndex
          ) {
            preMaterials[index] = material;
          }
        });
        return [...preMaterials];
      });
    });
  };

  const getNewMaterials = (materials: any[], material: any) => {
    const index = materials.findIndex((item: any) => {
      return (
        item.dxid === material.dxid && item.faceIndex === material.faceIndex
      );
    });
    if (index === -1) {
      // 没找到，就添加元素
      materials.push(material);
    } else {
      // 找到了，就替换
      materials[index] = material;
    }
    return materials;
  };

  const addMaterials = async () => {
    const material = await materialSetter.newMaterial();
    await materialSetter.setMaterial(dxid, faceIndex, material.id);
    // const material = await wsApi.addMaterials()
    // await wsApi.setMaterials(dxid, faceIndex, material.id)

    material['dxid'] = dxid;
    material['faceIndex'] = faceIndex;
    userEvents.emit(CMEVENTS.MATERIAL_ADDED, material);
  };

  const deleteMaterials = async () => {
    const selectedMaterial = _materials[selectedIndex];
    await materialSetter.cleanMaterial(
      selectedMaterial.dxid,
      selectedMaterial.faceIndex,
    );
    // await wsApi.setMaterials(selectedMaterial.dxid, selectedMaterial.faceIndex, -1)
    _materials.splice(selectedIndex, 1);
    setMaterials([..._materials]);
    const selectIndex = selectedIndex - 1;
    if (selectIndex > 0) {
      selectMaterial(selectIndex);
    }
  };

  const selectMaterial = (index: number) => {
    const material = _materials[index];
    setSelectedIndex(index);
    userEvents.emit(CMEVENTS.MATERIAL_SELECTED, material);
  };

  return (
    <Box sx={{ display: 'flex', flexDirection: 'row' }}>
      <StyledListBox>
        <List
          component='nav'
          dense>
          {_materials.map((material, index) => (
            <ListItemButton
              key={index}
              selected={selectedIndex === index}
              onClick={() => selectMaterial(index)}>
              <ListItemIcon sx={{ mt: 0, minWidth: 20 }}>
                {material.color === '' ? (
                  <BsBalloon />
                ) : (
                  <BsBalloonFill color={material.color} />
                )}
              </ListItemIcon>
              <ListItemText primary={material.name} />
              {material.color === '' ? '' : material.color}
            </ListItemButton>
          ))}
        </List>
      </StyledListBox>
      <StyledActionBox>
        <ButtonGroup
          orientation='vertical'
          size='small'>
          <Button
            size='small'
            onClick={() => {
              addMaterials();
            }}>
            <Add />
          </Button>
          <Button
            size='small'
            onClick={() => {
              deleteMaterials();
            }}>
            <Remove />
          </Button>
        </ButtonGroup>
      </StyledActionBox>
    </Box>
  );
}
